#!/usr/bin/env python

import getopt, sys, switch

def usage():
	print "usage: find_mac [-hl] [-a address] [-p port] [mac_address]"
	print "\t-a or --address\t specify the IP address of the switch"
	print "\t(if not specified the command will be executed on every switchs)"
	print "\t-h\t\t display this help"
	print "\t-p or --port\t display only results on this port"
	print
	print "The output format is:	mac	ip_switch	port_switch	vlan"
	print

def get_mac(ip, mac):
	tn = switch.connect(ip)
	if not tn:
		return ""
	name = switch.enable(tn)
	if not name:
		return ""
	output = switch.run_command(tn, "show mac-address-table address " + mac)
	switch.quit(tn)
	return output

def get_macs(ip):
        tn = switch.connect(ip)
        if not tn:
                return ""
        name = switch.enable(tn)
        if not name:
                return ""
        output = switch.run_command(tn, "show mac-address-table")
        switch.quit(tn)
        return output

def convert_to_cisco_mac(mac):
	mac_parts = mac.split(':')
	if len(mac_parts) != 6:
		raise "Mac Error" "Invalid MAC"
	i = 0
	new_mac = ''
	for part in mac_parts:
		if i != 0 and i%2 == 0:
			new_mac +=  '.'
		new_mac += part.lower()
		i += 1
	return new_mac

def convert_from_cisco_mac(mac):
	return mac[0] + mac[1] + ":" + mac[2] + mac[3] + ":" + mac[5] + mac[6] + ":" + mac[7] + mac[8] + ":" + mac[10] + mac[11] + ":" + mac[12] + mac[13]

def split_no_empty(str):
	elts = str.replace("\r", "").split(" ")
	splitted = []
	for elt in elts:
		if elt != "" and elt[0] != "-" and elt[0] != "\x08":
			splitted.append(elt)
	return splitted

def print_line(str, ip, filter_port):
	elt = split_no_empty(str)
	vlan = elt[0]
	mac = elt[1]
	port = elt[3][4:]
	if filter_port == "" or filter_port == port:
		print convert_from_cisco_mac(mac) + "\t" + ip + "\t" + port + "\t" + vlan 

def main(argv):
	try:
		opts, args = getopt.getopt(argv[1:], "a:hp:", ["help", "address=", "port="])
	except getopt.GetoptError:
		usage()
		sys.exit(2)
	list_switchs = []
	port = "";
	for opt, arg in opts:
		if opt in ("-h", "--help"):
			usage()
			sys.exit()
		elif opt in ("-a", "--address"):
			list_switchs.append(arg)
		elif opt in ("-p", "--port"):
			port = arg;
	if list_switchs == []:
		list_switchs = switch.get_switch_list()
	if args == []:
		for ip in list_switchs:
			output = get_macs(ip)
			lines = output.split("\n")
			for line in lines:
				if "Fa0/" in line:
					print_line(line, ip, port)
	else:
		new_mac = convert_to_cisco_mac(args[0])
		for ip in list_switchs:
			output = get_mac(ip, new_mac)
			lines = output.split("\n")
			for line in lines:
				if new_mac in line and "Fa0/" in line:
					print_line(line, ip, port)
					sys.exit(0)
		sys.exit(1)

if __name__ == '__main__':
	main(sys.argv)
	sys.exit(0)
